<div class="content-section introduction">
    <div class="feature-intro">
        <h1>Drag and Drop</h1>
        <p>pDraggable and pDroppable directives apply drag-drop behaviors to any element.</p>
    </div>
    <app-demoActions github="dragdrop"></app-demoActions>
</div>

<div class="content-section implementation">
    <div class="card">
        <h5>Drag and Drop to Table</h5>
        <div class="grid">
            <div class="col-12 md:col-6 drag-column">
                <div *ngFor="let product of availableProducts">
                    <div class="product-item" pDraggable="products" (onDragStart)="dragStart(product)" (onDragEnd)="dragEnd()">
                        <div class="image-container">
                                <img src="assets/showcase/images/demo/product/{{product.image}}" [alt]="product.name" class="product-image" />
                        </div>
                        <div class="product-list-detail">
                            <h5 class="mb-2">{{product.name}}</h5>
                            <i class="pi pi-tag product-category-icon"></i>
                            <span class="product-category">{{product.category}}</span>
                        </div>
                        <div class="product-list-action">
                            <h6 class="mb-2">${{product.price}}</h6>
                            <span [class]="'product-badge status-' + product.inventoryStatus.toLowerCase()">{{product.inventoryStatus}}</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-12 md:col-6 drop-column" pDroppable="products" (onDrop)="drop()">
            <p-table [value]="selectedProducts">
                <ng-template pTemplate="header">
                    <tr>
                        <th>ID</th>
                        <th>Category</th>
                        <th>Name</th>
                        <th>Price</th>
                    </tr>
                </ng-template>
                <ng-template pTemplate="body" let-product>
                    <tr>
                            <td>{{product.id}}</td>
                            <td>{{product.category}}</td>
                            <td>{{product.name}}</td>
                            <td>{{product.price}}</td>
                        </tr>
                    </ng-template>
                </p-table>
            </div>
        </div>
    </div>
</div>

<div class="content-section documentation">
    <p-tabView>
        <p-tabPanel header="Documentation">
            <h5>Import</h5>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;DragDropModule&#125; from 'primeng/dragdrop';
</app-code>

            <h5>Getting Started</h5>
            <p>pDraggable and pDroppable are attached to a target element to add drag-drop behavior. The value of a Directive attribute is required
            and it defines the scope to match draggables with droppables. Droppable scope can also be an array to accept multiple droppables.</p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;div pDraggable="dd"&gt;Draggable Div&lt;/div&gt;

&lt;div pDroppable="dd"&gt;Droppable Div&lt;/div&gt;
</app-code>

            <h5>Drag Handle</h5>
            <p>Drag handle is used to restrict dragging unless mousedown occurs on the specified element. Panel below can only be dragged using its header.</p>

            <app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;div pDraggable="pnl"  dragHandle=".p-panel-titlebar"&gt;
    &lt;p-panel header="Drag Header"&gt;
        Content
    &lt;/p-panel&gt;
&lt;/div&gt;
</app-code>

            <h5>Drop Indicator</h5>
            <p>When a suitable draggable enters a droppable area, the area gets <i>p-draggable-enter</i> class that can be used to style the droppable section.</p>

            <h5>Draggable</h5>
            <h4>Attributes</h4>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Type</th>
                            <th>Default</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>dragEffect</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Defines the cursor style, valid values are none, copy, move, link, copyMove, copyLink, linkMove and all.</td>
                        </tr>
                        <tr>
                            <td>dragHandle</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Selector to define the drag handle, by default anywhere on the target element is a drag handle to start dragging.</td>
                        </tr>
                        <tr>
                            <td>pDraggableDisabled</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Whether the element is draggable, useful for conditional cases.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h4>Events</h4>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>onDragStart</td>
                            <td>
                                event: browser event
                            </td>
                            <td>Callback to invoke when drag begins.</td>
                        </tr>
                        <tr>
                            <td>onDrag</td>
                            <td>
                                event: browser event
                            </td>
                            <td>Callback to invoke on dragging.</td>
                        </tr>
                        <tr>
                            <td>onDragEnd</td>
                            <td>
                                event: browser event
                            </td>
                            <td>Callback to invoke when drag ends.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Droppable</h5>
            <h4>Attributes</h4>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Type</th>
                            <th>Default</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>dropEffect</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Defines the cursor style on drag over, valid values are copy, relocate, link and move.</td>
                        </tr>
                        <tr>
                            <td>pDroppableDisabled</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Whether the element is droppable, useful for conditional cases.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h4>Events</h4>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>onDragEnter</td>
                            <td>
                                event: browser event
                            </td>
                            <td>Callback to invoke when a draggable enters drop area.</td>
                        </tr>
                        <tr>
                            <td>onDrop</td>
                            <td>
                                event: browser event
                            </td>
                            <td>Callback to invoke when a draggable is dropped onto drop area.</td>
                        </tr>
                        <tr>
                            <td>onDragLeave</td>
                            <td>
                                event: browser event
                            </td>
                            <td>Callback to invoke when a draggable leave drop area.</td>
                        </tr>
                    </tbody>
                </table>
            </div>


            <h5>Dependencies</h5>
            <p>Native HTML5 DragDrop.</p>
        </p-tabPanel>
        <p-tabPanel header="Source">
            <a href="https://github.com/primefaces/primeng/tree/master/src/app/showcase/components/dragdrop" class="btn-viewsource" target="_blank">
                <span>View on GitHub</span>
            </a>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
<h5>Drag and Drop to Table</h5>
&lt;div class="grid"&gt;
    &lt;div class="col-12 md:col-6 drag-column"&gt;
        &lt;div *ngFor="let product of availableProducts"&gt;
            &lt;div class="product-item" pDraggable="products" (onDragStart)="dragStart(product)" (onDragEnd)="dragEnd()"&gt;
                &lt;div class="image-container"&gt;
                        &lt;img src="assets/showcase/images/demo/product/&#123;&#123;product.image&#125;&#125;" [alt]="product.name" class="product-image" /&gt;
                &lt;/div&gt;
                &lt;div class="product-list-detail"&gt;
                    &lt;h5 class="mb-2"&gt;&#123;&#123;product.name&#125;&#125;&lt;/h5&gt;
                    &lt;i class="pi pi-tag product-category-icon"&gt;&lt;/i&gt;
                    &lt;span class="product-category"&gt;&#123;&#123;product.category&#125;&#125;&lt;/span&gt;
                &lt;/div&gt;
                &lt;div class="product-list-action"&gt;
                    &lt;h6 class="mb-2"&gt;$&#123;&#123;product.price&#125;&#125;&lt;/h6&gt;
                    &lt;span class="'product-badge status-'&#123;&#123;product.inventoryStatus.toLowerCase()&#125;&#125;"&gt;&#123;&#123;product.inventoryStatus&#125;&#125;&lt;/span&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="col-12 md:col-6 drop-column" pDroppable="products" (onDrop)="drop()"&gt;
    &lt;p-table [value]="selectedProducts"&gt;
        &lt;ng-template pTemplate="header"&gt;
            &lt;tr&gt;
                &lt;th&gt;ID&lt;/th&gt;
                &lt;th&gt;Category&lt;/th&gt;
                &lt;th&gt;Name&lt;/th&gt;
                &lt;th&gt;Price&lt;/th&gt;
            &lt;/tr&gt;
        &lt;/ng-template&gt;
        &lt;ng-template pTemplate="body" let-product&gt;
            &lt;tr&gt;
                    &lt;td&gt;&#123;&#123;product.id&#125;&#125;&lt;/td&gt;
                    &lt;td&gt;&#123;&#123;product.category&#125;&#125;&lt;/td&gt;
                    &lt;td&gt;&#123;&#123;product.name&#125;&#125;&lt;/td&gt;
                    &lt;td&gt;&#123;&#123;product.price&#125;&#125;&lt;/td&gt;
                &lt;/tr&gt;
            &lt;/ng-template&gt;
        &lt;/p-table&gt;
    &lt;/div&gt;
&lt;/div&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class DragDropDemo &#123;

    availableProducts: Product[];
    
    selectedProducts: Product[];
    
    draggedProduct: Product;
    
    constructor(private productService: ProductService) &#123; &#125;
    
    ngOnInit() &#123;
        this.selectedProducts = [];
        this.productService.getProductsSmall().then(products => this.availableProducts = products);
    &#125;
    
    dragStart(event,product: Product) &#123;
        this.draggedProduct = product;
    &#125;
    
    drop(event) &#123;
        if (this.draggedProduct) &#123;
            let draggedProductIndex = this.findIndex(this.draggedProduct);
            this.selectedProducts = [...this.selectedProducts, this.draggedProduct];
            this.availableProducts = this.availableProducts.filter((val,i) => i!=draggedProductIndex);
            this.draggedProduct = null;
        &#125;
    &#125;
    
    dragEnd(event) &#123;
        this.draggedProduct = null;
    &#125;
    
    findIndex(product: Product) &#123;
        let index = -1;
        for(let i = 0; i < this.availableProducts.length; i++) &#123;
            if (product.id === this.availableProducts[i].id) &#123;
                index = i;
                break;
            &#125;
        &#125;
        return index;
    &#125;

&#125;
</app-code>
<app-code lang="css" ngNonBindable ngPreserveWhitespaces>
:host ::ng-deep .drag-column &#123;
    padding-right: .5em;
&#125;

.drop-column &#123;
    border: 1px solid transparent;
    transition: border-color .2s;

    &.p-draggable-enter &#123;
        border-color: var(--primary-color); 
    &#125;
&#125;

.product-item &#123;
	display: flex;
	align-items: center;
	padding: .5rem;
    width: 100%;
    border-bottom: 1px solid var(--surface-d);

	img &#123;
		width: 75px;
        box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
        margin-right: 1rem;
	&#125;

	.product-list-detail &#123;
		flex: 1 1 0;
	&#125;

	.product-list-action &#123;
		display: flex;
        flex-direction: column;
        align-items: flex-end;
    &#125;

    .product-category-icon &#123;
        vertical-align: middle;
        margin-right: .5rem;
    &#125;

    .product-category &#123;
        vertical-align: middle;
        line-height: 1;
    &#125;
&#125;

[pDraggable] &#123;
    cursor: move;
&#125;

@media screen and (max-width: 576px) &#123;
    .product-item &#123;
        flex-wrap: wrap;

        .image-container &#123;
            width: 100%;
            text-align: center;
        &#125;

        img &#123;
            margin: 0 0 1rem 0;
            width: 100px;
        &#125;
    &#125;
&#125;
</app-code>
        </p-tabPanel>
    </p-tabView>
</div>
